/* 
  实现消息发布与订阅的功能
*/

(function (window) {
  const PubSub = {}
  let callbacksObj = {
    /* 消息名：{
      token1: 回调1,
      token2: 回调2,
      token3: 回调3,
    } */
  }
  // token自增
  let tokenId = 1

  // 1. 异步发布消息
  PubSub.publish = function (msgName, data) {
    let callbacks = callbacksObj[msgName];
    if (callbacks) {
      // 进行浅拷贝
      callbacks = Object.assign({}, callbacks)
      // 异步的进行调用
      setTimeout(() => {
        Object.values(callbacks).forEach(callback => {
          callback(data)
        })
      }, 0)
    }
  }

  // 2. 同步发送消息
  PubSub.publishAsync = function (msgName, data) {
    const callbacks = callbacksObj[msgName];

    if (callbacks) {
      // 异步的进行调用
      Object.values(callbacks).forEach(callback => {
        callback(data)
      })
    }
  }
  // 2. 订阅消息
  PubSub.subscribe = function (msgName, callback) {
    // token 值
    const token = 'token_' + ++tokenId;
    if (callbacksObj.hasOwnProperty(msgName)) {
      callbacksObj[msgName][token] = callback
    } else {
      callbacksObj[msgName] = {
        [token]: callback
      }
    }

    return token;
  }

  // 4. 取消订阅
  PubSub.unsubscribe = function (flag) {
    if (flag === null || flag == undefined) {
      // 取消所有的订阅
      callbacksObj = {}
    } else if (flag.indexOf('token_') === 0) {
      const callbacks = Object.values(callbacksObj);
      callbacks.forEach(item => {
        if (item.hasOwnProperty(flag)) {
          delete item[flag]
        }
      })
    } else {
      delete callbacksObj[flag]
    }
  }

  window.PubSub = PubSub
})(window)